/*

Gun Control Unit software by William Viker <william.viker@gmail.com>

Please inform me if you get anything useful out of this code - it's fun
to see other projects based or inspired on my own code/projects! 

*/

#include <LiquidCrystal.h>
#include <EEPROM.h>

int LoopCounter = 0;

/* Stepper motor stash */
int GatlingStepsTodo  = 0;
int PanStepsTodo      = 0;
int TiltStepsTodo     = 0;

int GatlingInStep     = 0;
int TiltInStep        = 0;
int PanInStep         = 0;

int GatlingDriverLast = 0;
int TiltDriverLast    = 0;
int PanDriverLast     = 0;

/* Stepper PINs */
int StepGatlingDir    = 2;
int StepGatlingStp    = 3;
int StepTiltDir       = 4;
int StepTiltStp       = 5;
int StepPanDir        = 6;
int StepPanStp        = 7;


/* Led PINs */
int LEDPower          = 40;
int LEDGatling        = 41;
int LEDPan            = 42;
int LEDTilt           = 43;
int LEDOxygen         = 44;
int LEDPropane        = 45;
int LEDExhaust        = 46;
int LEDIgnition       = 47;

/* Propane, Oxygen and Ignition */
int PINIgnition       = 49;
int PINPropane        = 48;
int PINOxygen         = 50;
int PINExhaust          = 51;

int scrollLast = 0;
int scrollPos = 0;
int scrollIn = 0;

int lcdLast = 0;

int preOxygenMap  = 1100;
int propaneMap    = 300;
int postOxygenMap = 140;

int preOxygenMS = preOxygenMap; 
int PropaneMS = propaneMap;
int postOxygenMS = postOxygenMap;
int IgnitionMS = 100;

int fireLast = 0;
int fireIn = 0;
int fireStage = 0;
int fireDiff = 0;


int stateOxygen = 0;
int statePropane = 0;
int stateIgnition = 0;
int stateExhaust = 0;

int programMode = 0;

int x = 0;

LiquidCrystal lcd(31,33,35,23,25,27,29);
  
void setup() {
 
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
 
  pinMode(PINOxygen, OUTPUT);
  pinMode(PINPropane, OUTPUT);
  pinMode(PINExhaust, OUTPUT);
  pinMode(PINIgnition, OUTPUT);
  
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setCursor(2,1);

  lcd.print("Starter mjukvare");
  lcd.blink();
  lcd.setCursor(0,2);
  lcd.print("OUTPUT ");
  
  pinMode(LEDPower, OUTPUT);
  pinMode(LEDGatling, OUTPUT);
  pinMode(LEDPan, OUTPUT);
  pinMode(LEDTilt, OUTPUT);
  pinMode(LEDOxygen, OUTPUT);
  pinMode(LEDPropane, OUTPUT);
  pinMode(LEDExhaust, OUTPUT);
  pinMode(LEDIgnition, OUTPUT);

  digitalWrite(LEDPower, HIGH);
  delay(70);
  digitalWrite(LEDPower, LOW);
  delay(200);
  digitalWrite(LEDPower, HIGH);
  delay(70);
  digitalWrite(LEDPower, LOW);
  delay(200);
  digitalWrite(LEDPower, HIGH);
  delay(70);
  digitalWrite(LEDPower, LOW);

  lcd.print("LEDS ");

  ledInit();
  
  lcd.print("SERIAL");
  
  lcd.setCursor(0,3);


  serialInit();  

  lcd.print("TIME ");
  
  GatlingDriverLast = millis();
  TiltDriverLast    = millis();
  PanDriverLast     = millis();

  lcd.print("LOOP");
  
  scrollIn = 1;
  scrollLast = millis();
  scrollPos = 0;
  
  lcd.noBlink();
  
  digitalWrite(LEDPower,HIGH);

  fireIn=1;
  fireLast=millis();

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("FLSH PROP MXNG DLAY");
  lcd.setCursor(0,2);
  lcd.print("MODE: ");

}

void loop() {

 
  int loopTime = millis();
  
  if (fireIn) {
    int fireTimer = loopTime - fireLast;
    if (fireTimer) {
      if (fireStage == 0) {
        exhaust(HIGH);
        oxygen(HIGH); 
        fireStage++;
      }
      else if (fireStage == 1) {
        if (fireTimer >= preOxygenMS) {
          oxygen(LOW);
          fireStage++;
        }
      }
      else if (fireStage == 2) {
        fireDiff = fireTimer;
        propane(HIGH);
        fireStage++;
      }
      else if (fireStage == 3) {
        if (fireTimer - fireDiff >= PropaneMS) {
          propane(LOW);
          fireStage++;
        }
      }
      else if (fireStage == 4) {
        fireDiff = fireTimer;
        oxygen(HIGH);
        fireStage++;
      }
      else if (fireStage == 5) {
        if (fireTimer - fireDiff >= postOxygenMS) {
          oxygen(LOW);
          exhaust(LOW);
          fireStage++;
        } 
      }
      else if (fireStage == 6) {
        fireDiff = fireTimer;
        ignition(HIGH);
        fireStage++; 
      }
      else if (fireStage == 7) {
        if (fireTimer - fireDiff >= IgnitionMS) {
          ignition(LOW);
          fireStage++;
        } 
      }
      else {
        fireIn=0;
        fireStage=0;
      }
    }
  } 
  else {
  
    if (loopTime - fireLast > 2000) {
      fireIn=1;
      fireLast=loopTime;
    } else {
      if (LoopCounter == 1) {
        lcd.setCursor(15,1);
        int delta = -2000 + loopTime - fireLast;
        lcd.print(delta);
      }
    }
     
  }
  
  if (LoopCounter++ == 2000) {

    programMode = map(analogRead(0),0,1023,1,3);
    lcd.setCursor(6,2);
    lcd.print(programMode);
/*
    preOxygenMS = map(analogRead(0),0,1024,50,preOxygenMap);
    PropaneMS = map(analogRead(1),0,1024,50,propaneMap);       
    postOxygenMS = map(analogRead(2),0,1024,50,postOxygenMap);
*/
       
    lcd.setCursor(0,1);
    lcd.print(preOxygenMS);
    lcd.print("   ");  

    lcd.setCursor(5,1);

    lcd.print(PropaneMS);
    lcd.print("   ");
  
    lcd.setCursor(10,1);
    lcd.print(postOxygenMS);
    lcd.print("  ");
 
    LoopCounter = 0;
  } 
  
  doSteps();

}

void serialInit() {
  Serial.begin(9600);
}


void ledInit() {

  digitalWrite(LEDGatling, HIGH);
  delay(80);
  digitalWrite(LEDGatling, LOW);

  digitalWrite(LEDPan, HIGH);
  delay(80);
  digitalWrite(LEDPan, LOW);
  
  digitalWrite(LEDTilt, HIGH);
  delay(80);
  digitalWrite(LEDTilt, LOW);

  digitalWrite(LEDOxygen, HIGH);
  delay(80);
  digitalWrite(LEDOxygen, LOW);

  digitalWrite(LEDPropane, HIGH);
  delay(80);
  digitalWrite(LEDPropane, LOW);

  digitalWrite(LEDExhaust, HIGH);
  delay(80);
  digitalWrite(LEDExhaust, LOW);

  digitalWrite(LEDIgnition, HIGH);
  delay(80);
  digitalWrite(LEDIgnition, LOW);

  for (int TestX = 47; TestX >= 41; TestX--) {
    digitalWrite(TestX,HIGH); 
    delay(80);
  }

  delay(500);
  for (int TestY = 41; TestY <= 47; TestY++) {
    digitalWrite(TestY,LOW); 
    delay(80);
  }

}


void oxygen(int state) {
  stateOxygen=state;
  if (state==1) { state=HIGH; }
  digitalWrite(LEDOxygen,state);
  digitalWrite(PINOxygen,state);
}

void propane(int state) {
  statePropane=state;
  if (state==1) { state=HIGH; }
  digitalWrite(LEDPropane,state);
  digitalWrite(PINPropane,state);
}

void ignition(int state) {
  stateIgnition=state;
  if (state==1) { state=HIGH; }
  digitalWrite(LEDIgnition,state);
  digitalWrite(PINIgnition,state);
}

void exhaust(int state) {
  stateExhaust=state;
  if (state==1) { state=HIGH; }
  digitalWrite(LEDExhaust,state);
  digitalWrite(PINExhaust,state);
}


void doSteps() {
  int now = millis();

  if (GatlingStepsTodo != 0) {
    digitalWrite(LEDGatling, HIGH);
    if (GatlingStepsTodo < 0) {
      analogWrite(StepGatlingDir, 255); // Reverse motion if negative
    } 
    else {
      analogWrite(StepGatlingDir, 0);   // Forward motion
    }
    if (GatlingDriverLast != now) {
      if (GatlingInStep) {
        analogWrite(StepGatlingStp, 0);
        GatlingInStep = 0;
        if (GatlingStepsTodo > 0) {
          GatlingStepsTodo--; 
        }
        else {
          GatlingStepsTodo++;
        }
        if (GatlingStepsTodo == 0) {
          digitalWrite(LEDGatling, LOW);  
        }

      }

      else {
        analogWrite(StepGatlingStp, 255);
        GatlingInStep = 1; 
      }   
      GatlingDriverLast = now;
    }
  }


  if (TiltStepsTodo != 0) {
    digitalWrite(LEDTilt, HIGH);
    if (TiltStepsTodo < 0) {
      analogWrite(StepTiltDir, 255); // Reverse motion if negative
    } 
    else {
      analogWrite(StepTiltDir, 0);   // Forward motion
    }
    if (TiltDriverLast != now) {
      if (TiltInStep) {
        analogWrite(StepTiltStp, 0);
        TiltInStep = 0;
        if (TiltStepsTodo > 0) {
          TiltStepsTodo--; 
        }
        else {
          TiltStepsTodo++;
        }
        if (TiltStepsTodo == 0) {
          digitalWrite(LEDTilt, LOW);  
        }

      }

      else {
        analogWrite(StepTiltStp,255);
        TiltInStep = 1; 
      }   
      TiltDriverLast = now;
    }
  }


  if (PanStepsTodo != 0) {
    digitalWrite(LEDPan, HIGH);
    if (PanStepsTodo < 0) {
      analogWrite(StepPanDir, 255); // Reverse motion if negative
    } 
    else {
      analogWrite(StepPanDir, 0);   // Forward motion
    }
    if (PanDriverLast != now) {
      if (PanInStep) {
        analogWrite(StepPanStp, 0);
        PanInStep = 0;
        if (PanStepsTodo > 0) {
          PanStepsTodo--; 
        }
        else {
          PanStepsTodo++;
        }
        if (PanStepsTodo == 0) {
          digitalWrite(LEDPan, LOW);  
        }
      }

      else {
        analogWrite(StepPanStp,255);
        PanInStep = 1; 
      }   
      PanDriverLast = now;
    }
  }  


}

